package com.uow.algdemo.ui;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import org.apache.http.util.EncodingUtils;

import com.uow.algdemo.algorithms.*;
import com.uow.algdemo.animation.*;
import com.uow.algdemo.ui.R;

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.view.Display;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.RelativeLayout;
import android.widget.Toast;
//Bj8ER5jm3WJ8
public class AnimationActivity extends Activity
{
    /**
     * Animation status of pasue or not.
     */
	private boolean pause = false;
    /**
     * Handler for whole control progress.
     */
	private Handler handler;
	
    /**
     * Text for string matching.
     */
	private String iText = "";
    /**
     * Pattern for string matching.
     */
	private String iPattern = "";
    /**
     * Integer array for sorting pass to algorithms.
     */
	private int[] iSort = new int[10];
    /**
     * Integer array for sorting before sorting.
     */
	private int[] iTemp = new int[10];
    /**
     * Number of value inputed for sorting algorithms.
     */
	private int iSortCount = 0;

    /**
     * Main interface of animation.
     */
	private AnimationInterface ai;

    /**
     * Button for show code.
     */
	private ImageButton buttonCode;
    /**
     * Button for reset input.
     */
	private ImageButton buttonReset;
    /**
     * Button for select history records.
     */
	private ImageButton buttonHistory;
    /**
     * Button for generate random values.
     */
	private ImageButton buttonAuto;
    /**
     * Button for input values.
     */
	private ImageButton buttonInput;
    /**
     * Button for select drawing tool of drawing line.
     */
	private ImageButton buttonLine;
    /**
     * Button for select drawing tool of drawing point.
     */
	private ImageButton buttonPoint;
    /**
     * Button for increase animation speed.
     */
	private ImageButton buttonAdd;
    /**
     * Button for decrease animation speed.
     */
	private ImageButton buttonMin;
    /**
     * Button for start animation.
     */
	private ImageButton buttonStart;
    /**
     * Button for pause animation.
     */
	private ImageButton buttonPause;
    /**
     * Button for stop animation.
     */
	private ImageButton buttonStop;
    /**
     * Button for go back.
     */
	private ImageButton buttonBack;
    /**
     * Button for next step.
     */
	private ImageButton buttonNext;
    /**
     * Button for save current values.
     */
	private ImageButton buttonSave;
    /**
     * Button for setting.
     */
	private ImageButton buttonSetting;

    /**
     * Integer for input of total disks and queens.
     */
	private int total = 0;
    /**
     * Current algorithm's id from main menu.
     */
	private int algorithmId = -1;
    /**
     * Algorithm's type.
     */
	private Type algorithmType;
    /**
     * Algorithm's name.
     */
	private String title;
    /**
     * Display for obtain current screen size.
     */
	private Display display;
    /**
     * Width of screen size in pixel.
     */
	private int resX = 0;
    /**
     * Height of screen size in pixel.
     */
	private int resY = 0;
    /**
     * Font of value on screen size in pixel.
     */
	private int pSize = 0;
    /**
     * Layout for animation.
     */
	private RelativeLayout layout;
    /**
     * Params of layout for animation.
     */
	private RelativeLayout.LayoutParams params;
    /**
     * Steps of animation.
     */
	private List<int[][]> steps = new ArrayList<int[][]>();
    /**
     * Enum of algorithm's type.
     */
	private enum Type {SORT, TREE, HANOI, QUEEN, GRAPH, MATCHING}
	@SuppressLint("HandlerLeak")
    /**
     * Main method of activity.
     */
	public void onCreate(Bundle savedInstanceState)
	{
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_animation);
    	algorithmId = Integer.parseInt((String) this.getIntent().getCharSequenceExtra("algorithmId"));
        title = (String) this.getIntent().getCharSequenceExtra("title");
        this.setTitle(title);

        buttonCode = (ImageButton) findViewById(R.id.buttonCode);
    	buttonReset = (ImageButton) findViewById(R.id.buttonReset);
    	buttonHistory = (ImageButton) findViewById(R.id.buttonHistory);
    	buttonAuto = (ImageButton) findViewById(R.id.buttonAuto);
    	buttonInput = (ImageButton) findViewById(R.id.buttonInput);
    	buttonLine = (ImageButton) findViewById(R.id.buttonLine);
    	buttonPoint = (ImageButton) findViewById(R.id.buttonPoint);
    	buttonAdd = (ImageButton) findViewById(R.id.buttonAdd);
    	buttonMin = (ImageButton) findViewById(R.id.buttonMin);
    	buttonStart = (ImageButton) findViewById(R.id.buttonStart);
    	buttonPause = (ImageButton) findViewById(R.id.buttonPause);
    	buttonStop = (ImageButton) findViewById(R.id.buttonStop);
    	buttonBack = (ImageButton) findViewById(R.id.buttonBack);
    	buttonNext = (ImageButton) findViewById(R.id.buttonNext);
    	buttonSave = (ImageButton) findViewById(R.id.buttonSave);
    	buttonSetting = (ImageButton) findViewById(R.id.buttonSetting);

    	int w = View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED);  
    	int h = View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED);  
    	buttonStart.measure(w, h);  
    	int height = buttonStart.getMeasuredHeight();  
    	display = getWindowManager().getDefaultDisplay();
        resX = display.getWidth() - 20;
        resY = display.getHeight() - height * 4 + 30;
        if(display.getWidth() < display.getHeight())
        {
        	pSize = (display.getWidth() - 200) / 10;
        }
        else
        {
        	pSize = (display.getHeight() - 200) / 10;
        }

		buttonStart.setEnabled(true);
		buttonPause.setEnabled(false);
		buttonStop.setEnabled(false);
		buttonBack.setEnabled(false);
		buttonNext.setEnabled(false);
		buttonAdd.setEnabled(false);
		buttonMin.setEnabled(false);

		layout = (RelativeLayout) findViewById(R.id.layout_animation);

		layout.setBackgroundResource(R.drawable.ic_background);
		params = new RelativeLayout.LayoutParams(resX, resY);
		params.addRule(RelativeLayout.CENTER_HORIZONTAL);
		params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
		params.bottomMargin = 10;

		if(algorithmId < 5) algorithmType = Type.SORT;
		if(algorithmId == 5 || algorithmId == 6) algorithmType = Type.TREE;
		if(algorithmId == 7) algorithmType = Type.HANOI;
		if(algorithmId == 8) algorithmType = Type.QUEEN;
		if(algorithmId >= 9 && algorithmId <= 11) algorithmType = Type.GRAPH;
		if(algorithmId > 11) algorithmType = Type.MATCHING;

    	handler = new Handler()
		{
			public void handleMessage(Message msg)
			{
				switch (msg.what)
				{
					case 1:
					{
						if(ai.getStatus())
						{
							buttonStart.setEnabled(true);
							buttonPause.setEnabled(false);
							buttonStop.setEnabled(false);
							buttonBack.setEnabled(false);
							buttonNext.setEnabled(false);
							buttonAdd.setEnabled(false);
							buttonMin.setEnabled(false);
			        		buttonInput.setEnabled(true);
			        		buttonPoint.setEnabled(true);
			        		buttonLine.setEnabled(true);
			        		buttonAuto.setEnabled(true);
			        		buttonHistory.setEnabled(true);
			        		buttonReset.setEnabled(true);
						}
						else
						{
							handler.sendEmptyMessageDelayed(1, 20);
						}
						break;
					}
					case 2:
					{
		        		buttonStart.setEnabled(false);
		        		buttonPause.setEnabled(true);
		        		buttonStop.setEnabled(true);
		        		buttonBack.setEnabled(false);
		        		buttonNext.setEnabled(false);
		        		buttonAdd.setEnabled(true);
		        		buttonMin.setEnabled(true);
		        		buttonInput.setEnabled(false);
		        		buttonPoint.setEnabled(false);
		        		buttonLine.setEnabled(false);
		        		buttonAuto.setEnabled(false);
		        		buttonHistory.setEnabled(false);
		        		buttonReset.setEnabled(false);
		        		break;
					}
				}
				super.handleMessage(msg);
			}
		};

		if(algorithmType == Type.GRAPH)
		{
			ai = new AnimationGraph(AnimationActivity.this, resX, resY, pSize);
			layout.addView((View) ai,params);
		}

		if(algorithmType == Type.QUEEN || algorithmType == Type.HANOI)
        {
        	buttonSave.setVisibility(4);
        	buttonSetting.setVisibility(4);
        	buttonReset.setVisibility(4);
        	buttonHistory.setVisibility(4);
        }

		if(algorithmType != Type.GRAPH)
        {
        	buttonPoint.setVisibility(4);
        	buttonLine.setVisibility(4);
        }

		if(algorithmType != Type.SORT && algorithmType != Type.MATCHING && algorithmType != Type.TREE)
        {
        	buttonAuto.setVisibility(4);
        	buttonInput.setVisibility(4);
        }

		buttonStart.setOnClickListener(new View.OnClickListener()
		{
            public void onClick(View v)
            {
            	if(!pause)
            	{
            		if(algorithmType == Type.SORT)
            		{
	        			if(iSortCount > 2)
	        			{
	            			Sort so = new Sort(iSort);
	            			switch(algorithmId)
	            			{
	            				case 0:
	    	            			so.sortQuick();
	    	            			break;
	            				case 1:
			            			so.sortBubble();
			            			break;
	            				case 2:
			            			so.sortSelection();
			            			break;
	            				case 3:
			            			so.sortInsertion();
			            			break;
	            				case 4:
			            			so.sortShell();
			            			break;
	            			}

	                		layout.removeView((View)ai);
			        		ai = new AnimationSort(AnimationActivity.this, iSort, so.getSteps(), resX, resY, pSize);
			                layout.addView((View) ai,params);
			                ai.runAnimation();
			                handler.sendEmptyMessage(1);
			                handler.sendEmptyMessage(2);
	        			}
                    	else
                    	{
                    		Toast.makeText(AnimationActivity.this, "Not enough numbers for sorting", Toast.LENGTH_SHORT).show();
                    		return;
                    	}
            		}
            		
            		if(algorithmType == Type.HANOI)
            		{
	                    final EditText inputValue = new EditText(AnimationActivity.this);
	                    inputValue.setInputType(0x00000002);
	                    AlertDialog.Builder builder = new AlertDialog.Builder(AnimationActivity.this);
	                    builder.setTitle("Input number of disks (3-8)");
	                    builder.setIcon(android.R.drawable.ic_dialog_info);
	                    builder.setView(inputValue);
	                    builder.setNegativeButton("Cancel", null);
	                    builder.setPositiveButton("Ok", new DialogInterface.OnClickListener()
	                    {
	                        public void onClick(DialogInterface dialog, int which)
	                        {
	                        	if(inputValue.getText().toString().length() > 0)
	                        	{
		                        	int input = Integer.parseInt(inputValue.getText().toString());
		                        	if(input > 2 && input < 9)
		                        	{
		                        		total = input;
					                    Hanoi han = new Hanoi(total);
						            	han.runHanoiTower();

		                        		layout.removeView((View)ai);
						        		ai = new AnimationHanoi(AnimationActivity.this, total, han.getSteps(), resX, resY);
						                layout.addView((View) ai,params);
						            	ai.runAnimation();
						            	handler.sendEmptyMessage(1);
						                handler.sendEmptyMessage(2);
		                        	}
		                        	else
		                        	{
		                        		Toast.makeText(AnimationActivity.this, "Input is not vaild", Toast.LENGTH_SHORT).show();
		                        	}
	                        	}
	                        	else
	                        	{
	                        		Toast.makeText(AnimationActivity.this, "Input is not vaild", Toast.LENGTH_SHORT).show();
	                        	}
	                        }
	                    });
	                    builder.show();
            		}
            		if(algorithmType == Type.QUEEN)
            		{
	                    final EditText inputValue = new EditText(AnimationActivity.this);
	                    inputValue.setInputType(0x00000002);
	                    AlertDialog.Builder builder = new AlertDialog.Builder(AnimationActivity.this);
	                    builder.setTitle("Input number of queens (4-8)");
	                    builder.setIcon(android.R.drawable.ic_dialog_info);
	                    builder.setView(inputValue);
	                    builder.setNegativeButton("Cancel", null);
	                    builder.setPositiveButton("Ok", new DialogInterface.OnClickListener()
	                    {
	                        public void onClick(DialogInterface dialog, int which)
	                        {
	                        	if(inputValue.getText().toString().length() > 0)
	                        	{
		                        	int input = Integer.parseInt(inputValue.getText().toString());
		                        	if(input > 3 && input < 9)
		                        	{
		                        		total = input;
		        	                	Queen qu = new Queen(total);
		        	                	qu.backTracking();

		                        		layout.removeView((View)ai);
		        	            		ai = new AnimationQueen(AnimationActivity.this,qu.getSteps(),total,resX,resY);
		        	            		layout.addView((View) ai,params);
		        	            		ai.runAnimation();

		        	            		handler.sendEmptyMessage(1);
		        		                handler.sendEmptyMessage(2);
		                        	}
		                        	else
		                        	{
		                        		Toast.makeText(AnimationActivity.this, "Input is not vaild", Toast.LENGTH_SHORT).show();
		                        	}
	                        	}
	                        	else
	                        	{
	                        		Toast.makeText(AnimationActivity.this, "Input is not vaild", Toast.LENGTH_SHORT).show();
	                        	}
	                        }
	                    });
	                    builder.show();
            		}
            		if(algorithmType == Type.GRAPH)
            		{
            			int[][] count = ai.sendMessage(5);
            			if(count[0][0] > 0 && count[0][1] > 0)
            			{
		            		final Graph ga = new Graph(ai.sendMessage(3));
	            			switch(algorithmId)
	            			{
	            				case 9:
	            				{
	            					final String pName = "ABCDEFGHIJ";
	        	                    final EditText startValue = new EditText(AnimationActivity.this);
	        	                    startValue.setInputType(0x00001001);
	        	                    AlertDialog.Builder builder = new AlertDialog.Builder(AnimationActivity.this);
	        	                    builder.setTitle("Input start point:");
	        	                    builder.setIcon(android.R.drawable.ic_dialog_info);
	        	                    builder.setView(startValue);
	        	                    builder.setNegativeButton("Cancel", null);
	        	                    builder.setPositiveButton("Ok", new DialogInterface.OnClickListener()
	        	                    {
	        	                        public void onClick(DialogInterface dialog, int which)
	        	                        {
	        	                        	if(startValue.getText().toString().length() > 0)
	        	                        	{
	        		                        	final int start = pName.indexOf(startValue.getText().toString().toUpperCase()) + 1;
	        		                        	if(start > 0 && start < 9)
	        		                        	{
	        		        	                    final EditText endValue = new EditText(AnimationActivity.this);
	        		        	                    endValue.setInputType(0x00001001);
	        		        	                    AlertDialog.Builder builder = new AlertDialog.Builder(AnimationActivity.this);
	        		        	                    builder.setTitle("Input end point");
	        		        	                    builder.setIcon(android.R.drawable.ic_dialog_info);
	        		        	                    builder.setView(endValue);
	        		        	                    builder.setNegativeButton("Cancel", null);
	        		        	                    builder.setPositiveButton("Ok", new DialogInterface.OnClickListener()
	        		        	                    {
	        		        	                        public void onClick(DialogInterface dialog, int which)
	        		        	                        {
	        		        	                        	if(endValue.getText().toString().length() > 0)
	        		        	                        	{
	        		        		                        	int end = pName.indexOf(endValue.getText().toString().toUpperCase()) + 1;
	        		        		                        	if(end > 0 && end < 9)
	        		        		                        	{
	        		        		    	            			ga.shortestDijkstra(start, end);
	        		        		    		            		ai.setSteps(ga.getSteps());
	        		        		    		            		ai.runAnimation();
	        		        		    			        		handler.sendEmptyMessage(1);
	        		        		    			                handler.sendEmptyMessage(2);
	        		        		                        	}
	        		        		                        	else
	        		        		                        	{
	        		        		                        		Toast.makeText(AnimationActivity.this, "Input is not vaild", Toast.LENGTH_SHORT).show();
	        		        		                        	}
	        		        	                        	}
	        		        	                        	else
	        		        	                        	{
	        		        	                        		Toast.makeText(AnimationActivity.this, "Input is not vaild", Toast.LENGTH_SHORT).show();
	        		        	                        	}
	        		        	                        }
	        		        	                    });
	        		        	                    builder.show();
	        		                        	}
	        		                        	else
	        		                        	{
	        		                        		Toast.makeText(AnimationActivity.this, "Input is not vaild", Toast.LENGTH_SHORT).show();
	        		                        	}
	        	                        	}
	        	                        	else
	        	                        	{
	        	                        		Toast.makeText(AnimationActivity.this, "Input is not vaild", Toast.LENGTH_SHORT).show();
	        	                        	}
	        	                        }
	        	                    });
	        	                    builder.show();
	    	            			break;
	            				}
	            				case 10:
			            			ga.spanningTreeKruskal();
				            		ai.setSteps(ga.getSteps());
				            		ai.runAnimation();
					        		handler.sendEmptyMessage(1);
					                handler.sendEmptyMessage(2);
			            			break;
	            				case 11:
			            			ga.spanningTreePrim();
				            		ai.setSteps(ga.getSteps());
				            		ai.runAnimation();
					        		handler.sendEmptyMessage(1);
					                handler.sendEmptyMessage(2);
			            			break;
	            			}
            			}
            			else
            			{
            				Toast.makeText(AnimationActivity.this, "Please draw a graph first.", Toast.LENGTH_SHORT).show();
            			}
            		}
            		if(algorithmType == Type.MATCHING)
            		{
            			if(iText.length() != 0)
            			{
	    	                final EditText inputPattern = new EditText(AnimationActivity.this);
	    	                AlertDialog.Builder builder = new AlertDialog.Builder(AnimationActivity.this);
	    	                builder.setTitle("Input string for search");
	    	                builder.setIcon(android.R.drawable.ic_dialog_info);
	    	                builder.setView(inputPattern);
	    	                builder.setNegativeButton("Cancel", null);
	    	                builder.setPositiveButton("Ok", new DialogInterface.OnClickListener()
	    	                {
	    	                    public void onClick(DialogInterface dialog, int which)
	    	                    {
	    	                    	if(inputPattern.getText().toString().length() < iText.length() && inputPattern.getText().toString().length() > 0)
	    	                    	{
	    	                    		iPattern = inputPattern.getText().toString();
	    				        		StringMatching s = new StringMatching(iText,iPattern);
	    		            			switch(algorithmId)
	    		            			{
	    		            				case 12:
	    		    	            			s.stringMatchingKnuthMorrisPratt();
	    		    	            			break;
	    		            				case 13:
	    				            			s.stringMatchingMorrisPratt();
	    				            			break;
	    		            				case 14:
	    				            			s.stringMatchingKarpRabin();
	    				            			break;
	    		            				case 15:
	    				            			s.stringMatchingBoyerMoore();
	    				            			break;
	    		            			}
	
	    				        		layout.removeView((View) ai);
						        		ai = new AnimationStringMatching(AnimationActivity.this, iText, iPattern, s.getSteps(), s.getSkipTable(), resX, resY, pSize, algorithmId);
						        		layout.addView((View) ai,params);
						        		ai.runAnimation();
						        		handler.sendEmptyMessage(1);
						                handler.sendEmptyMessage(2);
	    	                    	}
	    	                    	else
	    	                    	{
	    	            				Toast.makeText(AnimationActivity.this, "Input is not vaild.", Toast.LENGTH_SHORT).show();
	    	                    	}
	    	                    }
	    	                });
	    	                builder.show();
            			}
            			else
            			{
            				Toast.makeText(AnimationActivity.this, "Input text first.", Toast.LENGTH_SHORT).show();
            			}
            		}
            		
                	if(algorithmType == Type.TREE)
                	{
	        			if(iSortCount > 2)
	        			{
	        				String[] options = new String[3];
	        				options[0] = "Pre Order";
	        				options[1] = "In Order";
	        				options[2] = "Post Order";
		                	AlertDialog.Builder builder = new AlertDialog.Builder(AnimationActivity.this);
		                	builder.setTitle("History records");
		                    builder.setIcon(android.R.drawable.ic_dialog_info);
		                    builder.setSingleChoiceItems(options, 0, new DialogInterface.OnClickListener()
		                    {
		                         public void onClick(DialogInterface dialog, int which)
		                         {
		 		                    layout.removeView((View)ai);
					        		ai = new AnimationTree(AnimationActivity.this, iSort, resX, resY, pSize, algorithmId);
					                layout.addView((View) ai,params);
					                ai.sendMessage(which);
					                ai.runAnimation();
					                ((AnimationTree) ai).printOrder(AnimationActivity.this);
					                handler.sendEmptyMessage(1);
					                handler.sendEmptyMessage(2);

					                dialog.dismiss();
		                         }
		                      }
		                    );
		                    builder.setNegativeButton("Cancel", null);
		                    builder.show();
	        			}
	        			else
	        			{
            				Toast.makeText(AnimationActivity.this, "Not enough data.", Toast.LENGTH_SHORT).show();
	        			}
                	}
            	}
            	else
            	{
        			pause = false;
        			ai.resumeAnimation();
        			
        			handler.sendEmptyMessage(2);
            	}
            }
        });

    	buttonPause.setOnClickListener(new View.OnClickListener()
    	{
            public void onClick(View v)
            {
	            pause = true;
	            ai.pauseAnimation();

        		buttonStart.setEnabled(true);
        		buttonPause.setEnabled(false);
        		buttonStop.setEnabled(true);
        		buttonBack.setEnabled(true);
        		buttonNext.setEnabled(true);
        		buttonAdd.setEnabled(true);
        		buttonMin.setEnabled(true);
            }
        });

    	buttonStop.setOnClickListener(new View.OnClickListener()
    	{
            public void onClick(View v)
            {
        		pause = false;
        		ai.stopAnimation();

				buttonStart.setEnabled(true);
				buttonPause.setEnabled(false);
				buttonStop.setEnabled(false);
				buttonBack.setEnabled(false);
				buttonNext.setEnabled(false);
				buttonAdd.setEnabled(false);
				buttonMin.setEnabled(false);
        		buttonInput.setEnabled(true);
        		buttonPoint.setEnabled(true);
        		buttonLine.setEnabled(true);
        		buttonAuto.setEnabled(true);
        		buttonHistory.setEnabled(true);
        		buttonReset.setEnabled(true);
            }
        });

    	buttonNext.setOnClickListener(new View.OnClickListener()
    	{
            public void onClick(View v)
            {
        		ai.nextStep();
            }
        });

    	buttonBack.setOnClickListener(new View.OnClickListener()
    	{
            public void onClick(View v)
            {
        		ai.lastStep();
            }
        });

        buttonAdd.setOnClickListener(new View.OnClickListener()
        {
            public void onClick(View v)
            {
            	int cSpeed = ai.getSpeed();
            	cSpeed--;
            	if(cSpeed > 0)
            	{
            		ai.setSpeed(cSpeed);
            	}
            }
        });

        buttonMin.setOnClickListener(new View.OnClickListener()
        {
            public void onClick(View v)
            {
            	int cSpeed = ai.getSpeed();
            	cSpeed++;
            	if(cSpeed < 21)
            	{
            		ai.setSpeed(cSpeed);
            	}
            }
        });

        buttonPoint.setOnClickListener(new View.OnClickListener()
        {
            public void onClick(View v)
            {
            	ai.sendMessage(1);
            }
        });

        buttonLine.setOnClickListener(new View.OnClickListener()
        {
            public void onClick(View v)
            {
            	ai.sendMessage(2);
            }
        });

        buttonInput.setOnClickListener(new View.OnClickListener()
        {
            public void onClick(View v)
            {
            	if(algorithmType == Type.SORT)
	            {
	                final EditText inputValue = new EditText(AnimationActivity.this);
	                inputValue.setInputType(0x00000002);
	                AlertDialog.Builder builder = new AlertDialog.Builder(AnimationActivity.this);
	                builder.setTitle("Input value");
	                builder.setIcon(android.R.drawable.ic_dialog_info);
	                builder.setView(inputValue);
	                builder.setNegativeButton("Cancel", null);
	                builder.setPositiveButton("Ok", new DialogInterface.OnClickListener()
	                {
	                    public void onClick(DialogInterface dialog, int which)
	                    {
	                    	if(iSortCount < 10)
	                    	{
	                    		if(inputValue.getText().toString().length() > 0)
	                    		{
			                    	iTemp[iSortCount] = Integer.parseInt(inputValue.getText().toString());
			                    	iSortCount++;
				            		if(iSortCount > 0)
				            		{
				            			iSort = new int[iSortCount];
				            			for(int i = 0; i < iSortCount; i++)
				            			{
				            				iSort[i] = iTemp[i];
				            			}
				            			layout.removeView((View) ai);
						        		ai = new AnimationSort(AnimationActivity.this, iSort, steps, resX, resY, pSize);
						                layout.addView((View) ai,params);
				            		}
	                            	else
	                            	{
	                            		Toast.makeText(AnimationActivity.this, "Input is not vaild", Toast.LENGTH_SHORT).show();
	                            	}
	                    		}
	                    	}
                        	else
                        	{
                        		Toast.makeText(AnimationActivity.this, "Already reach maximume size", Toast.LENGTH_SHORT).show();
                        	}
	                    }
	                });
	                builder.show();
	            }
            	if(algorithmType == Type.MATCHING)
            	{
	                final EditText inputText = new EditText(AnimationActivity.this);
	                AlertDialog.Builder builder = new AlertDialog.Builder(AnimationActivity.this);
	                builder.setTitle("Input string for search");
	                builder.setIcon(android.R.drawable.ic_dialog_info);
	                builder.setView(inputText);
	                builder.setNegativeButton("Cancel", null);
	                builder.setPositiveButton("Ok", new DialogInterface.OnClickListener()
	                {
	                    public void onClick(DialogInterface dialog, int which)
	                    {
	                    	final int length = inputText.getText().toString().length();
	                    	if(length > 2)
	                    	{
		                    	iText = inputText.getText().toString();
		            			layout.removeView((View) ai);
		            			int[] table = new int[0];
				        		ai = new AnimationStringMatching(AnimationActivity.this, iText, "", steps, table, resX, resY, pSize, algorithmId);
				                layout.addView((View) ai,params);
	                    	}
	                    	else
                        	{
                        		Toast.makeText(AnimationActivity.this, "Input is not vaild", Toast.LENGTH_SHORT).show();
                        	}
	                    }
	                });
	                builder.show();
            	}
            	if(algorithmType == Type.TREE)
            	{
	                final EditText inputValue = new EditText(AnimationActivity.this);
	                inputValue.setInputType(0x00000002);
	                AlertDialog.Builder builder = new AlertDialog.Builder(AnimationActivity.this);
	                builder.setTitle("Input value");
	                builder.setIcon(android.R.drawable.ic_dialog_info);
	                builder.setView(inputValue);
	                builder.setNegativeButton("Cancel", null);
	                builder.setPositiveButton("Ok", new DialogInterface.OnClickListener()
	                {
	                    public void onClick(DialogInterface dialog, int which)
	                    {
	                    	if(iSortCount < 10)
	                    	{
	                    		if(inputValue.getText().toString().length() > 0)
	                    		{
			                    	iTemp[iSortCount] = Integer.parseInt(inputValue.getText().toString());
			                    	iSortCount++;
				            		if(iSortCount > 0)
				            		{
				            			iSort = new int[iSortCount];
				            			for(int i = 0; i < iSortCount; i++)
				            			{
				            				iSort[i] = iTemp[i];
				            			}
				            			layout.removeView((View) ai);
						        		ai = new AnimationTree(AnimationActivity.this, iSort, resX, resY, pSize, algorithmId);
						                layout.addView((View) ai,params);
				            		}
			            		}
                            	else
                            	{
                            		Toast.makeText(AnimationActivity.this, "Input is not vaild", Toast.LENGTH_SHORT).show();
                            	}
	                    	}
                        	else
                        	{
                        		Toast.makeText(AnimationActivity.this, "Already reach maximume size", Toast.LENGTH_SHORT).show();
                        	}
	                    }
	                });
	                builder.show();
            	}
            }
        });

        buttonAuto.setOnClickListener(new View.OnClickListener()
        {
            public void onClick(View v)
            {
            	Random randomAuto = new Random();
            	if(algorithmType == Type.SORT)
            	{
	            	iSort = new int[8];
	            	int num =0;
	            	for(int i = 0; i < 8; i++)
	            	{
	                    num = Math.abs(randomAuto.nextInt() % 99);
	                    iTemp[i] = num;
	            	}
	            	iSortCount = 8;
	    			iSort = new int[iSortCount];
	    			for(int i = 0; i < iSortCount; i++)
	    			{
	    				iSort[i] = iTemp[i];
	    			}
	    			layout.removeView((View) ai);
	        		ai = new AnimationSort(AnimationActivity.this, iSort, steps, resX, resY, pSize);
	                layout.addView((View) ai,params);
            	}
            	if(algorithmType == Type.MATCHING)
            	{
            		String base = "abcdefghijklmnopqrstuvwxyz";
	            	iText = "";
	            	StringBuffer buffer = new StringBuffer();
	            	int num = 0;
	            	for(int i = 0; i < 10; i++)
	            	{
	                    num = Math.abs(randomAuto.nextInt() % 26);
	                    buffer.append(base.charAt(num));
	            	}
	            	iText = buffer.toString();
        			int[] table = new int[0];
	    			layout.removeView((View) ai);
	        		ai = new AnimationStringMatching(AnimationActivity.this, iText, "", steps, table, resX, resY, pSize, algorithmId);
	                layout.addView((View) ai,params);
            	}
            	if(algorithmType == Type.TREE)
            	{
	            	iSort = new int[8];
	            	int num =0;
	            	for(int i = 0; i < 8; i++)
	            	{
	                    num = Math.abs(randomAuto.nextInt() % 99);
	                    iTemp[i] = num;
	            	}
	            	iSortCount = 8;
	    			iSort = new int[iSortCount];
	    			for(int i = 0; i < iSortCount; i++)
	    			{
	    				iSort[i] = iTemp[i];
	    			}
	    			layout.removeView((View) ai);
	        		ai = new AnimationTree(AnimationActivity.this, iSort, resX, resY, pSize, algorithmId);
	                layout.addView((View) ai,params);
            	}
            }
        });

        buttonReset.setOnClickListener(new View.OnClickListener()
        {
            public void onClick(View v)
            {
            	iSort = new int[8];
            	iSortCount = 0;
            	iText = "";
            	iPattern = "";
            	layout.removeView((View) ai);
        		if(algorithmId >= 9 && algorithmId <= 11)
        		{
        			ai = new AnimationGraph(AnimationActivity.this, resX, resY, pSize);
        			layout.addView((View) ai,params);
        		}
            }
        });

        buttonCode.setOnClickListener(new View.OnClickListener()
        {
            public void onClick(View v)
            {
            	String res = "";
            	String file = "";
            	switch(algorithmId)
            	{
            		case 0:
            			file = "quick.txt";
            			break;
            		case 1:
            			file = "bubble.txt";
            			break;
            		case 2:
            			file = "selection.txt";
            			break;
            		case 3:
            			file = "insertion.txt";
            			break;
            		case 4:
            			file = "shell.txt";
            			break;
            		case 5:
            			file = "";
            			break;
            		case 6:
            			file = "";
            			break;
            		case 7:
            			file = "hanoi.txt";
            			break;
            		case 8:
            			file = "queen.txt";
            			break;
            		case 9:
            			file = "dijkstra.txt";
            			break;
            		case 10:
            			file = "kruskal.txt";
            			break;
            		case 11:
            			file = "prim.txt";
            			break;
            		case 12:
            			file = "kmp.txt";
            			break;
            		case 13:
            			file = "kmp.txt";
            			break;
            		case 14:
            			file = "rk.txt";
            			break;
            		case 15:
            			file = "bm.txt";
            			break;
            	}
            	InputStream in;
				try
				{
					in = getResources().getAssets().open(file);
	                int length = in.available();  
	                byte[] buffer = new byte[length];  
	                in.read(buffer);
	                res = EncodingUtils.getString(buffer, "UTF-8");  
	                in.close();
				}
				catch (IOException e)
				{
					e.printStackTrace();
				}
				AlertDialog.Builder code = new AlertDialog.Builder(AnimationActivity.this);   
            	code.setTitle("Pseudocode");
            	code.setMessage(res);
            	code.setPositiveButton("Back", null);
            	code.show();
            }
        });

        buttonHistory.setOnClickListener(new View.OnClickListener()
        {
            public void onClick(View v)
            {
            	try
            	{
            		String filename = "";
            		switch(algorithmType)
            		{
            			case SORT:
            			{
            				filename = "sort.txt";
            				break;
            			}
            			case MATCHING:
            			{
            				filename = "string.txt";
            				break;
            			}
            			case GRAPH:
            			{
            				filename = "graph.txt";
            				break;
            			}
            			case TREE:
            			{
            				filename = "sort.txt";
            				break;
            			}
						default:
							break;
            		}
                    FileInputStream fin = openFileInput(filename);
                    byte [] buffer = new byte[fin.available()];
                    fin.read(buffer);
                    InputStream in = new ByteArrayInputStream(buffer);
                    BufferedReader br = new BufferedReader(new InputStreamReader(in));
                    int count = 0;
                    final String[] res = new String[112];
                    String tmp = br.readLine();
                    if(tmp != null)
                    {
                    	while(tmp != null)
                    	{
                    		res[count] = tmp;
                    		count++;
                    		tmp = br.readLine();
                    	}
                    }
                    
                    if(algorithmType != Type.GRAPH)
                    {
	                    final String[] histories;
	                    if(count < 6)
	                    {
		                	histories = new String[count];
		                	for(int i = 0; i < count; i++)
		                	{
		                		histories[i] = res[i];
		                	}
	                    }
	                    else
	                    {
		                	histories = new String[5];
		                	for(int i = 0; i < 5; i++)
		                	{
		                		histories[i] = res[i];
		                	}
	                    }
	                	AlertDialog.Builder builder = new AlertDialog.Builder(AnimationActivity.this);
	                	builder.setTitle("History records");
	                    builder.setIcon(android.R.drawable.ic_dialog_info);
	                    builder.setSingleChoiceItems(histories, 0, new DialogInterface.OnClickListener()
	                    {
	                         public void onClick(DialogInterface dialog, int which)
	                         {
	                            String tmp = histories[which];
	                            if(algorithmType == Type.SORT)
	                            {
		                            String[] tmpi = tmp.split(" ");
		                            iSort = new int[tmpi.length];
		                            for(int j = 0; j < tmpi.length; j++)
		                            {
		                            	iSort[j] = Integer.parseInt(tmpi[j]);
		                            }
		                            iSortCount = iSort.length;
		        	    			layout.removeView((View) ai);
		        	        		ai = new AnimationSort(AnimationActivity.this, iSort, steps, resX, resY, pSize);
		        	                layout.addView((View) ai,params);
	        						Toast.makeText(AnimationActivity.this, "Load number array successfully.", Toast.LENGTH_SHORT).show();
	                            }
	                            if(algorithmType == Type.MATCHING)
	                            {
	                            	iText = tmp;
			            			int[] table = new int[0];
	            	    			layout.removeView((View) ai);
	            	        		ai = new AnimationStringMatching(AnimationActivity.this, iText, "", steps, table, resX, resY, pSize, algorithmId);
	            	                layout.addView((View) ai,params);
	        						Toast.makeText(AnimationActivity.this, "Load text successfully.", Toast.LENGTH_SHORT).show();
	                            }
	                            if(algorithmType == Type.TREE)
	                            {
		                            String[] tmpi = tmp.split(" ");
		                            iSort = new int[tmpi.length];
		                            for(int j = 0; j < tmpi.length; j++)
		                            {
		                            	iSort[j] = Integer.parseInt(tmpi[j]);
		                            }
		                            iSortCount = iSort.length;
		        	    			layout.removeView((View) ai);
					        		ai = new AnimationTree(AnimationActivity.this, iSort, resX, resY, pSize, algorithmId);
		        	                layout.addView((View) ai,params);
	        						Toast.makeText(AnimationActivity.this, "Load number array successfully.", Toast.LENGTH_SHORT).show();
	                            }
	                            dialog.dismiss();
	                         }
	                      }
	                    );
	                    builder.setNegativeButton("Cancel", null);
	                    builder.show();
	                    fin.close();
                    }
                    else
                    {
		                AlertDialog.Builder builder = new AlertDialog.Builder(AnimationActivity.this);
		                builder.setTitle("Load graph history records?");
		                builder.setIcon(android.R.drawable.ic_dialog_info);
		                builder.setNegativeButton("Cancel", null);
		                builder.setPositiveButton("Ok", new DialogInterface.OnClickListener()
		                {
		                    public void onClick(DialogInterface dialog, int which)
		                    {
                            	int[][] cArray = new int[10][2];
                            	int[][] gArray = new int[10][10];
                            	for(int q = 0; q < 10; q++)
                            	{
                            		for(int p = 0; p < 10; p++)
                            		{
                            			gArray[q][p] = 1000;
                            		}
                            	}
                            	int c = 0;
                            	String line = res[c];
                            	c++;
                            	int pCount = Integer.parseInt(line);
                            	for(int i = 0; i < pCount; i++)
                            	{
                            		line = res[c + i];
                            		String[] tmpi = line.split(" ");
                            		int index = Integer.parseInt(tmpi[0]);
                            		int x = Integer.parseInt(tmpi[1]);
                            		int y = Integer.parseInt(tmpi[2]);
                            		cArray[index][0] = x;
                            		cArray[index][1] = y;
                            	}
                            	c = c + pCount;
                            	line = res[c];
                            	c++;
                            	int eCount = Integer.parseInt(line);
                            	for(int i = 0; i < eCount; i++)
                            	{
                            		line = res[c+i];
                            		String[] tmpi = line.split(" ");
                            		int a = Integer.parseInt(tmpi[0]);
                            		int b = Integer.parseInt(tmpi[1]);
                            		int l = Integer.parseInt(tmpi[2]);
                            		gArray[a][b] = l;
                            	}
            	    			layout.removeView((View) ai);
            	        		ai = new AnimationGraph(AnimationActivity.this, gArray, cArray, resX, resY, pSize);
            	                layout.addView((View) ai,params);
        						Toast.makeText(AnimationActivity.this, "Load graph successfully.", Toast.LENGTH_SHORT).show();
		                    }
		                });
		                builder.show();
                    }
                }
                catch(Exception e)
                {
                	e.printStackTrace();
                }
            }
        });

        buttonSave.setOnClickListener(new View.OnClickListener()
        {
            public void onClick(View v)
            {
            	if(algorithmType == Type.SORT)
            	{
					try
					{
						FileOutputStream fout = openFileOutput("sort.txt", MODE_APPEND);
						String tmp = "";
						for(int i = 0; i < iSort.length; i++)
						{
							if(i == iSort.length - 1)
								tmp = tmp + iSort[i] + "\r";
							else
								tmp = tmp + iSort[i] + " ";
						}
						byte [] bytes = tmp.getBytes();
						fout.write(bytes);
						fout.close();
						Toast.makeText(AnimationActivity.this, "Current number array saved.", Toast.LENGTH_SHORT).show();
					}
					catch(Exception e)
					{
						e.printStackTrace();
					}
            	}
            	
            	if(algorithmType == Type.MATCHING)
            	{
					try
					{
						FileOutputStream fout = openFileOutput("string.txt", MODE_APPEND);
						byte [] bytes = (iText + '\r').getBytes();
						fout.write(bytes);
						fout.close();
						Toast.makeText(AnimationActivity.this, "Current text saved.", Toast.LENGTH_SHORT).show();
					}
					catch(Exception e)
					{
						e.printStackTrace();
					}
            	}
            	
            	if(algorithmType == Type.GRAPH)
            	{
					try
					{
						FileOutputStream fout = openFileOutput("graph.txt", MODE_PRIVATE);
						int[][] gArray = ai.sendMessage(3);
						int[][] cArray = ai.sendMessage(4);
						int pCount = 0;
						int eCount = 0;
						byte[] tByte;
						for(int i = 0; i < 10; i++)
						{
							if(cArray[i][0] != 0 && cArray[i][1] != 0)
							{
								pCount++;
							}
						}
						tByte = (pCount + "\r").getBytes();
						fout.write(tByte);
						for(int i = 0; i < 10; i++)
						{
							if(cArray[i][0] != 0 && cArray[i][1] != 0)
							{
								byte [] bytes = (i + " " + cArray[i][0] + " " + cArray[i][1] + "\r").getBytes();
								fout.write(bytes);
							}
						}
						for(int i = 0; i < 10; i++)
						{
							for(int j = 0; j < 10; j++)
							{
								if(gArray[i][j] != 1000)
								{
									eCount++;
								}
							}
						}
						tByte = (eCount + "\r").getBytes();
						fout.write(tByte);
						for(int i = 0; i < 10; i++)
						{
							for(int j = 0; j < 10; j++)
							{
								if(gArray[i][j] != 1000)
								{
									byte [] bytes = (i + " " + j + " " + gArray[i][j] + "\r").getBytes();
									fout.write(bytes);
								}
							}
						}
						fout.close();
						Toast.makeText(AnimationActivity.this, "Current graph saved.", Toast.LENGTH_SHORT).show();
					}
					catch(Exception e)
					{
						e.printStackTrace();
					}
            	}
            	
            	if(algorithmType == Type.TREE)
            	{
					try
					{
						FileOutputStream fout = openFileOutput("sort.txt", MODE_APPEND);
						String tmp = "";
						for(int i = 0; i < iSort.length; i++)
						{
							if(i == iSort.length - 1)
								tmp = tmp + iSort[i] + "\r";
							else
								tmp = tmp + iSort[i] + " ";
						}
						byte [] bytes = tmp.getBytes();
						fout.write(bytes);
						fout.close();
						Toast.makeText(AnimationActivity.this, "Current number array saved.", Toast.LENGTH_SHORT).show();
					}
					catch(Exception e)
					{
						e.printStackTrace();
					}
				}
            }
        });

        buttonSetting.setOnClickListener(new View.OnClickListener()
        {
            public void onClick(View v)
            {
            	Intent i = new Intent();
            	i.setClass(AnimationActivity.this,SettingActivity.class);
            	AnimationActivity.this.startActivity(i);
            }
        });
    }
}
